package controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

public class FileIO {

	private JFileChooser inputFC, outputFC;
	private File inputFile;
	private File outputFile;
	private InputStream resource;
	FileIO(){
		inputFC = new JFileChooser();
		inputFC.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		outputFC = new JFileChooser();
	}
	public File[] parseForFilesAndDirectories(String[] stringFiles){
		LinkedList<File> listFiles = new LinkedList<File>();
		File file;
		for (String stringFile : stringFiles){
			file = new File(stringFile);
			if (file.isFile()||file.isDirectory()){
				listFiles.add(file);
			}
		}
		
		return listFiles.toArray(new File[0]);
	}
	public boolean selectInputFile(JFrame frame){
		//allows the user to open a file dialog and select a file
		int returnVal = inputFC.showDialog(frame, "Select");
		if (returnVal == JFileChooser.APPROVE_OPTION){
			inputFile = inputFC.getSelectedFile();
			return true;
		}
		return false;
	}
	public boolean selectOutputFile(JFrame frame, String extension){
		//allows the user to open a file dialog and select a file
		outputFC.setSelectedFile(new File(getFileNameWithoutExtension(inputFile.getPath())+extension ));
		int returnVal = outputFC.showSaveDialog(frame);
		if (returnVal == JFileChooser.APPROVE_OPTION){
			outputFile = outputFC.getSelectedFile();
			return true;
		}
		return false;
	}
	public void setInputFCExtensions(String[] extensions){
		//sets the input file chooser to use the extensions specified in the String array
		String nameString = extensions[0];
		for (int i = 1; i<extensions.length;i++){
			nameString+=", "+extensions[i];
		}
		inputFC.setFileFilter(new ExtensionFileFilter(nameString, extensions));
	}
	public void setOutputFCExtensions(String[] extensions){
		//sets the input file chooser to use the extensions specified in the String array
		String nameString = extensions[0];
		for (int i = 1; i<extensions.length;i++){
			nameString+=", "+extensions[i];
		}
		outputFC.setFileFilter(new ExtensionFileFilter(nameString, extensions));
	}
	public String getFileNameWithoutExtension(String fileName){
		//gets a fileName without extensions
		int i =fileName.length()-1;
		while(fileName.charAt(i)!='.'|| i==0)
			i--;
		
		if (i!=0)
			fileName = fileName.substring(0, i);
		
		return fileName;
	}
	public boolean setResourceFile(String url, JFrame frame){
		//tries to open the resource indicated by the string, such as:
		//"/resource/USCIS Approved Patches.xls"
		try {
			resource = this.getClass().getResourceAsStream(url);
			if (resource == null){
				JOptionPane.showMessageDialog(frame, "Resource is null");
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(frame, "Exception: "+e.getMessage());
			return false;
		}
		return true;
	}
	public void setInputFile(JFrame frame, String filename){
		//sets the input file based on a string
		inputFile = new File(filename);
		
		if(!inputFile.exists()){
			JOptionPane.showMessageDialog(frame, "The file was not found. Make sure that you selected an appropriate file.");
		}
	}
	public void setInputFile(JFrame frame, File file) {
		//sets the input file based on a string
		inputFile = file;
		
		if(!inputFile.exists()){
			JOptionPane.showMessageDialog(frame, "The file was not found. Make sure that you selected an appropriate file.");
		}
	}
	public void setOutputFilename(String filename){
		outputFile = new File(filename);
	}
	public File getInputFile() throws FileNotFoundException{
		//returns input file if it exists, throws error otherwise
		if (inputFile!=null && inputFile.exists())
			return inputFile;	
		
		return null;
		
	}
	public File getOutputFile()  {
		//returns input file if it exists, throws error otherwise
			return outputFile;	

	}
	public String getSelectedFileOrDirectoryFullPath(){
		if (inputFile.exists()){
			return inputFile.getAbsolutePath();
		}
		return "";
	}
	public InputStream getResourceStream() throws FileNotFoundException{
		
			return resource;
		
		
		//throw new FileNotFoundException();
	}
	public String getInputFileData(JFrame frame){
		String data = "";
		if (inputFile.exists()){
			try {
				Scanner scanner = new Scanner(inputFile);
				while (scanner.hasNext()){
					data = data+scanner.nextLine();
				}
				
			} catch (FileNotFoundException e) {
				JOptionPane.showMessageDialog(frame, "The file was not found. Are you sure that you selected an appropriate file?");
			}
		}
		return data;
	}
	public String getInputFilePath(){
		if (inputFile.exists())
			return inputFile.getAbsolutePath();
		else
			return "File not found.";
	}
	public void confirmWrite(String data, JFrame frame){
		if (outputFile.exists()){
			if (JOptionPane.showConfirmDialog(frame, "A file currently exists at:\n"+outputFile.getAbsolutePath()+"\nOverwrite?") == JOptionPane.YES_OPTION){
				if(outputFile.canWrite()){
					outputFile.delete();
					write(data, frame);
				}
				else
					JOptionPane.showMessageDialog(frame, "The file is currently in use and write-locked. Please try again");
			}
		}
		else {
			write(data, frame);
		}
	}
	private void write(String data, JFrame frame){
		try {
			
			PrintWriter writer = new PrintWriter(new FileWriter(outputFile));
			String[] tokens = data.split("\n");
			for(int i = 0; i<tokens.length; i++){
				writer.println(tokens[i]);
			}
			writer.close();
		} catch (IOException e) {
			JOptionPane.showMessageDialog(frame, "There was a Java IOException \n"+e.getStackTrace());
		}
	}
	
	class ExtensionFileFilter extends FileFilter {
		  String description;

		  String extensions[];

		  public ExtensionFileFilter(String description, String extension) {
		    this(description, new String[] { extension });
		  }

		  public ExtensionFileFilter(String description, String extensions[]) {
		    if (description == null) {
		      this.description = extensions[0];
		    } else {
		      this.description = description;
		    }
		    this.extensions = (String[]) extensions.clone();
		    toLower(this.extensions);
		  }

		  private void toLower(String array[]) {
		    for (int i = 0, n = array.length; i < n; i++) {
		      array[i] = array[i].toLowerCase();
		    }
		  }

		  public String getDescription() {
		    return description;
		  }

		  public boolean accept(File file) {
		    if (file.isDirectory()) {
		      return true;
		    } else {
		      String path = file.getAbsolutePath().toLowerCase();
		      for (int i = 0, n = extensions.length; i < n; i++) {
		        String extension = extensions[i];
		        if ((path.endsWith(extension) && (path.charAt(path.length() - extension.length() - 1)) == '.')) {
		          return true;
		        }
		      }
		    }
		    return false;
		  }
		}

}
